package org.compiere.process;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.logging.Level;

import org.adempiere.exceptions.AdempiereException;
import org.compiere.model.MBPartner;
import org.compiere.model.Mhrmmedicare;
import org.compiere.model.Mhrmmedicareline;
import org.compiere.model.Mhrmmedicarelinelist;
import org.compiere.model.Mhrmsalaryemployee;
import org.compiere.model.X_C_BPartner;
import org.compiere.model.X_hrm_medicare;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.eevolution.model.X_HR_Employee;
import extend.org.compiere.hrm.TaxCompute;
import extend.org.compiere.hrm.TaxVariable;
import extend.org.compiere.hrm.TypePayment;
import extend.org.compiere.utils.Util;

public class GenerateMedicarePayment extends SvrProcess {
	
	private int C_BPartner_ID = 0;
	private int HR_Block_ID  = 0;
	private int HR_Department_ID  = 0;
	double SUM = .0;
	Timestamp dateFrom = null;
		
	/**	Employee List	*/
	private MBPartner[] m_lines;
	
	/** declare medical care variables */	
	private Mhrmmedicare medicare = null;
	private Mhrmmedicareline medicareline = null;
	private Mhrmmedicarelinelist medicarelist = null;
	private TaxVariable taxcomp = null;
	
	/** */
	String closeTax = "N";
	
	/** Set calendar */
	Calendar cMonth = Calendar.getInstance();
	
	@Override
	protected void prepare() {
		
		ProcessInfoParameter[] para = getParameter();
		for (int i = 0; i < para.length; i++)
		{
				String name = para[i].getParameterName();
				if (name.equals("CloseTax"))
					closeTax = para[i].getParameter().toString();
				else
					log.log(Level.INFO, "Unknown Parameter: " + name);			
		}
		
		medicare = new Mhrmmedicare(getCtx(), getRecord_ID(), null);
	}

	@Override
	protected String doIt() throws Exception {		
		
		//
		C_BPartner_ID = medicare.getC_BPartner_ID();
		HR_Block_ID = medicare.getHR_Block_ID();
		HR_Department_ID = medicare.getHR_Department_ID();
		dateFrom = medicare.getStartDate();
		
		MBPartner bp = new MBPartner(getCtx(), medicare.getC_BPartner_ID(), null);
		X_HR_Employee he = null;
		m_lines = bp.getPartnerEmployeeDate(C_BPartner_ID, HR_Block_ID, HR_Department_ID, dateFrom, true);
				
		//
		for(MBPartner b: m_lines){
				// Title
			 Mhrmsalaryemployee mhrmsle = Mhrmsalaryemployee.getSalary(b.getC_BPartner_ID(), dateFrom);						
				if (mhrmsle != null){
				  he = X_HR_Employee.getHR_Employee(b.getC_BPartner_ID(),null);
				   if (he.getC_BPartner_ID() == 0)
						throw new AdempiereException ("Info about employee was empty");
				   medicareline = Mhrmmedicareline.getMedicareRec(b.getC_BPartner_ID(), medicare.gethrm_medicare_ID());
				   if (medicareline == null)
					   medicareline = new Mhrmmedicareline(getCtx(), 0, null);
				   medicareline.sethrm_medicare_ID(medicare.gethrm_medicare_ID());
				   medicareline.setC_BPartner_ID(b.getC_BPartner_ID());
				   medicareline.setHR_Department_ID(he.getHR_Department_ID());
				   medicareline.setHR_Job_ID(he.getHR_Job_ID());
				   medicareline.setStartDate(medicare.getStartDate());
				   medicareline.setEndDate(medicare.getEndDate());
				   medicareline.sethrm_total(medicare.gethrm_total());
				   medicareline.saveEx();
				  
				   dateFrom = medicareline.getStartDate();
				   int Month = Util.getMonth(medicareline.getStartDate(), medicareline.getEndDate());
				   for (int i = 0; i <= Month; i++){
					   int M = Month + 1;
					   cMonth.setTime(dateFrom);
					   medicarelist = Mhrmmedicarelinelist.getMedicareList(b.getC_BPartner_ID(), dateFrom, medicareline.gethrm_medicare_line_ID());
					   if (medicarelist == null)
						  medicarelist = new Mhrmmedicarelinelist(getCtx(), 0, null);
					   medicarelist.sethrm_medicare_line_ID(medicareline.gethrm_medicare_line_ID());
					   medicarelist.setC_BPartner_ID(medicareline.getC_BPartner_ID());
					   medicarelist.setDateFrom(dateFrom);
					   medicarelist.sethrm_medicaretype(medicare.gethrm_medicaretype());
					   BigDecimal DIV = medicareline.gethrm_total().divide(new BigDecimal(M), BigDecimal.ROUND_UP);
					   medicarelist.sethrm_total(DIV);					   
					   SUM = DIV.doubleValue();			   
					  
					   /** Generate employee tax */
					   String type = TypePayment.MEDICARE;
					   if(medicare.gethrm_medicaretype().equals(X_hrm_medicare.HRM_MEDICARETYPE_Profit)) 
						   type = TypePayment.PROFIT; 
						taxcomp =  TaxCompute.GetTax(medicareline.getC_BPartner_ID(), SUM, dateFrom, type);
															
						BigDecimal amount = Mhrmsalaryemployee.getFullSalary(b.getC_BPartner_ID(), dateFrom);
						if (amount.compareTo(new BigDecimal(0)) == 0){
							medicarelist.sethrm_IPN(new BigDecimal(0));
							medicarelist.sethrm_amount(new BigDecimal(taxcomp.getTOTAL() + taxcomp.getIPN()));
						}else{
							medicarelist.sethrm_IPN(new BigDecimal(taxcomp.getIPN()));
							medicarelist.sethrm_amount(new BigDecimal(taxcomp.getTOTAL()));
						}
						medicarelist.sethrm_OPV(new BigDecimal(taxcomp.getOPV()));
						medicarelist.sethrm_CNalog(new BigDecimal(taxcomp.getCNALOG()));
						medicarelist.sethrm_COtch(new BigDecimal(taxcomp.getCOTCH()));											
						medicarelist.saveEx();
						
					   cMonth.add(Calendar.MONTH, 1);
					   dateFrom = new Timestamp(cMonth.getTimeInMillis());
				   }
				   
				   if (closeTax.equals("Y")){
					   medicarelist.setProcessed(true);
					   medicareline.setProcessed(true);
					   medicareline.saveEx();
					   medicarelist.saveEx();
				    }				   
				}
		}
		if (closeTax.equals("Y")){
			   medicare.setProcessed(true);
			   medicareline.saveEx();
			   medicare.saveEx();
		    }
	
		return Msg.translate(Env.getCtx(), "Success");
	}

}
